package utils

import (
	"encoding/json"
	"github.com/gomodule/redigo/redis"
)

var (
	RedisConn *redis.Pool
	//最大空闲连接数
	MaxIdle = 10
	//在给定时间内，允许分配的最大连接数（当为零时，没有限制）
	MaxActive = 0
	//在给定时间内将会保持空闲状态，若到达时间限制则关闭连接（当为零时，没有限制）
	IdleTimeout = 0
)

//func init() {
//	conf, err := config.NewConfig("ini", "conf/app.conf")
//	if err != nil {
//		log.Fatal("配置文件载入错误")
//	}
//
//	redisSection, err := conf.GetSection("redis")
//	if err != nil {
//		log.Fatal("配置文件载入错误-财务数据库-section载入失败")
//	}
//
//	redishost := redisSection["redishost"]
//	redispassword := redisSection["redispassword"]
//	RedisConn = &redis.Pool{
//		MaxIdle:     MaxIdle,
//		MaxActive:   MaxActive,
//		IdleTimeout: 240 * time.Second,
//		Dial: func() (redis.Conn, error) {
//			c, err := redis.Dial("tcp", redishost)
//			if err != nil {
//				log.Fatal("redis dial error:", err.Error())
//				return nil, err
//			}
//			if redispassword != "" {
//
//				if _, err := c.Do("AUTH", redispassword); err != nil {
//					c.Close()
//					fmt.Println(redispassword, "redispassword")
//					//log.Fatal("password wrong error:", err.Error())
//					return nil, err
//				}
//			}
//			return c, nil
//		},
//		TestOnBorrow: func(c redis.Conn, t time.Time) error {
//			_, err := c.Do("PING")
//			return err
//		},
//	}
//
//}

func Set(key string, data interface{}, time int) error {
	conn := RedisConn.Get()
	defer conn.Close()

	value, err := json.Marshal(data)
	if err != nil {
		return err
	}

	_, err = conn.Do("SET", key, value)
	if err != nil {
		return err
	}

	_, err = conn.Do("EXPIRE", key, time)
	if err != nil {
		return err
	}

	return nil
}

// SetNoExpire 设置不过期数据
func SetNoExpire(key string, data interface{}) error {
	conn := RedisConn.Get()
	defer conn.Close()

	value, err := json.Marshal(data)
	if err != nil {
		return err
	}

	_, err = conn.Do("SET", key, value)
	if err != nil {
		return err
	}

	return nil
}

func Exists(key string) bool {
	conn := RedisConn.Get()
	defer conn.Close()

	exists, err := redis.Bool(conn.Do("EXISTS", key))
	if err != nil {
		return false
	}

	return exists
}

func Get(key string) ([]byte, error) {
	conn := RedisConn.Get()
	defer conn.Close()

	reply, err := redis.Bytes(conn.Do("GET", key))
	if err != nil {
		return nil, err
	}

	return reply, nil
}

func Delete(key string) (bool, error) {
	conn := RedisConn.Get()
	defer conn.Close()

	return redis.Bool(conn.Do("DEL", key))
}

func LikeDeletes(key string) error {
	conn := RedisConn.Get()
	defer conn.Close()

	keys, err := redis.Strings(conn.Do("KEYS", "*"+key+"*"))
	if err != nil {
		return err
	}

	for _, key := range keys {
		_, err = Delete(key)
		if err != nil {
			return err
		}
	}

	return nil
}

// GetRedisGather 获取redis集合的数据
func GetRedisGatherList(key, sort string, start, end int) (list []int, err error) {
	conn := RedisConn.Get()
	defer conn.Close()
	return redis.Ints(conn.Do(sort, key, start, end, "withscores"))
}

// GetRedisSetZscore 获取集合成员的score
func GetRedisSetZscore(key string, value interface{}) (score int, err error) {
	conn := RedisConn.Get()
	defer conn.Close()
	return redis.Int(conn.Do("ZSCORE", key, value))
}

// GetRedisGather 获取redis集合的数据
func GetRedisGatherCount(key string) (count interface{}, err error) {
	conn := RedisConn.Get()
	count, err = conn.Do("ZCARD", key)
	if err != nil {
		return
	}
	return
}

func GetWithType(key string, v interface{}) error {
	data, err := Get(key)
	if err != nil {
		return err
	}

	return json.Unmarshal(data, v)
}

// GetIncr 设置键自增
func GetIncr(key string) (int64, error) {
	conn := RedisConn.Get()
	return redis.Int64(conn.Do("INCR", key))
}

func ExistsKey(key string) bool {
	conn := RedisConn.Get()
	defer conn.Close()

	exists, err := redis.Bool(conn.Do("EXISTS", key))
	if err != nil {
		return false
	}

	return exists
}

func SetRedisExpire(key string, data interface{}, time int) error {
	conn := RedisConn.Get()
	defer conn.Close()

	value, err := json.Marshal(data)
	if err != nil {
		return err
	}

	_, err = conn.Do("SET", key, value)
	if err != nil {
		return err
	}

	_, err = conn.Do("EXPIRE", key, time)
	if err != nil {
		return err
	}

	return nil
}

func GetRedis(key string) ([]byte, error) {
	conn := RedisConn.Get()
	defer conn.Close()

	reply, err := redis.Bytes(conn.Do("GET", key))
	if err != nil {
		return nil, err
	}

	return reply, nil
}

func SetRedis(key string, data interface{}) error {
	conn := RedisConn.Get()
	defer conn.Close()

	value, err := json.Marshal(data)
	if err != nil {
		return err
	}

	_, err = conn.Do("SET", key, value)
	if err != nil {
		return err
	}
	return nil
}
